using System;

namespace LannyPractiseCode
{
    public class CircleSingleLinkedList
    {
        private Boy first=null; //第一个指针不会动！
        //添加节点，构建环形链表
        public void Add(int Nums)
        {
            if(Nums<1)//数据校验
                return;
            Boy curBoy=null;
            for(int i=1;i<=Nums;i++)
            {
                Boy boy=new Boy(i);
                if(i==1)
                {
                    first=boy;
                    first.Next=first;//构建环。。
                    curBoy=first;//curBoy指向first节点
                }
                else
                {
                    curBoy.Next=boy;//!!!!
                    boy.Next=first;//!!!!
                    curBoy=boy;//!!!!
                }
            }
        }

        public void ShowBoy()
        {
            if(first==null)
            {
                System.Console.WriteLine("列表为空~");
                return;
            }

            Boy curBoy=first;

            while(true)
            {
                System.Console.WriteLine(curBoy.No);
                if(curBoy.Next==first)
                    break;//遍历完成。
                curBoy=curBoy.Next;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="startNo">表示从第几个小孩开始数</param>
        /// <param name="countNum">表示数几下</param>
        /// <param name="Nums">最初有多少还在在圈中</param>
        public void AcountBoy(int startNo,int countNum,int nums)
        {
            if(first==null || startNo<0 || startNo>nums)
            {
                Console.WriteLine("非法数据。");
                return;
            }

            //创建要给辅助指针，帮助完成小孩出圈。
            Boy helper=first;
            //需求创建一-个辅助指针(变量) helper ，事先应该指向环形链表的最后这个节点
            while(true)
            {
                if(helper.Next==first)
                    break;
                helper=helper.Next;
            }

            //小孩报数前，先让first和helper移动k - 1次
            for(int i=0;i<startNo-1;i++)
            {
                first=first.Next;
                helper=helper.Next;
            }

            //当小孩报数时，让first和helper指针同时的移动m-1次，然后出圈
            //这里是一个循环操作，知道圈中只有一个节点
            while(true)
            {
                if(helper==first)//说明圈中只有一个节点
                    break;
                //让first和helper指针同时的移动countNum - 1
                for(int j=0;j<countNum-1;j++)
                {
                    first=first.Next;
                    helper=helper.Next;
                }

                //这时first指向的节点，就是要出圈的小孩节点
                System.Console.WriteLine("小孩出圈： "+first.No);
                //这时将first指向的小孩节点出圈
                first=first.Next;
                helper.Next=first;
            }
            System.Console.WriteLine("最后出圈的小孩："+first.No);
        }
    }
}